package com.smartfactory.sail.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.smartfactory.sail.config.BizzException;
import com.smartfactory.sail.entity.*;
import com.smartfactory.sail.entity.enums.DeviceStatusEnum;
import com.smartfactory.sail.entity.enums.OrderItemStatusEnum;
import com.smartfactory.sail.entity.enums.StorageStatusEnum;
import com.smartfactory.sail.entity.enums.StorageType;
import com.smartfactory.sail.mapper.ItemWorkingprocedureInfoMapper;
import com.smartfactory.sail.service.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * <p>
 * 产品生产流程详情 服务实现类
 * </p>
 *
 * @author 王巨壁
 * @since 2019-08-13
 */
@Service
@Transactional
public class ItemWorkingprocedureInfoServiceImpl extends ServiceImpl<ItemWorkingprocedureInfoMapper, ItemWorkingprocedureInfo> implements IItemWorkingprocedureInfoService {
    private IItemWorkingprocedureService iItemWorkingprocedureService;
    private ItemWorkingprocedureInfoMapper itemWorkingprocedureInfoMapper;
    private IStorageRecordService iStorageRecordService;
    private IOrderItemService iOrderItemService;
    private IDeviceService iDeviceService;
    private IItemWorkingprocedureDeviceService iItemWorkingprocedureDeviceService;
    private IItemService iItemService;
    private IWasteService iWasteService;
    private IItemWorkingprocedurePickingService itemWorkingprocedurePickingService;

    public ItemWorkingprocedureInfoServiceImpl(IItemWorkingprocedureService iItemWorkingprocedureService, ItemWorkingprocedureInfoMapper itemWorkingprocedureInfoMapper, IStorageRecordService iStorageRecordService, IOrderItemService iOrderItemService, IDeviceService iDeviceService, IItemWorkingprocedureDeviceService iItemWorkingprocedureDeviceService, IItemService iItemService, IWasteService iWasteService, IItemWorkingprocedurePickingService itemWorkingprocedurePickingService) {
        this.iItemWorkingprocedureService = iItemWorkingprocedureService;
        this.itemWorkingprocedureInfoMapper = itemWorkingprocedureInfoMapper;
        this.iStorageRecordService = iStorageRecordService;
        this.iOrderItemService = iOrderItemService;
        this.iDeviceService = iDeviceService;
        this.iItemWorkingprocedureDeviceService = iItemWorkingprocedureDeviceService;
        this.iItemService = iItemService;
        this.iWasteService = iWasteService;
        this.itemWorkingprocedurePickingService = itemWorkingprocedurePickingService;
    }

    @Override
    public int scanInsert(ItemWorkingprocedureInfo itemWorkingprocedureInfo) throws BizzException {

        itemWorkingprocedurePickingService.commitCheck(itemWorkingprocedureInfo.getItemId(),
                itemWorkingprocedureInfo.getOrderId(),
                itemWorkingprocedureInfo.getUserId(),
                itemWorkingprocedureInfo.getWorkingProcedureId(),
                itemWorkingprocedureInfo.getCompleteNumber(),
                itemWorkingprocedureInfo.getProblemNumber()
        );

        ItemWorkingprocedure itemWorkingprocedure = iItemWorkingprocedureService.getById(itemWorkingprocedureInfo.getWorkingProcedureId());
        LambdaQueryWrapper<ItemWorkingprocedureInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ItemWorkingprocedureInfo::getItemId, itemWorkingprocedureInfo.getItemId());
        queryWrapper.eq(ItemWorkingprocedureInfo::getOrderId, itemWorkingprocedureInfo.getOrderId());
        queryWrapper.eq(ItemWorkingprocedureInfo::getWorkingProcedureId, itemWorkingprocedureInfo.getWorkingProcedureId());
        List<ItemWorkingprocedureInfo> workingprocedureInfos = itemWorkingprocedureInfoMapper.selectList(queryWrapper);
        OrderItem orderItem = iOrderItemService.findByOrderIdAndItemId(itemWorkingprocedureInfo.getItemId(), itemWorkingprocedureInfo.getOrderId());
        if (null == orderItem)
            throw new IllegalArgumentException("订单产品不存在");
        Integer orderSize = orderItem.getSize();
        int completeNumber = itemWorkingprocedureInfo.getCompleteNumber();
        int problemNumber = itemWorkingprocedureInfo.getProblemNumber();
        Item item = iItemService.getById(orderItem.getItemId());
        Integer scrapRate = item.getScrapRate();
        int totalSize = (int) Math.ceil(orderSize * (100 + scrapRate) * 1.0 / 100);

        int completeNumberTotal = workingprocedureInfos.stream().mapToInt(ItemWorkingprocedureInfo::getCompleteNumber).sum();
        int problemNumberTotal = workingprocedureInfos.stream().mapToInt(ItemWorkingprocedureInfo::getProblemNumber).sum();
        //当前工序报废数
        int wasteSize = iWasteService.wasteSize(itemWorkingprocedureInfo.getItemId(), itemWorkingprocedureInfo.getOrderId(), itemWorkingprocedureInfo.getWorkingProcedureId());
        //截止当前工序报废总数
        int wastePreSum = iWasteService.wastePreSum(itemWorkingprocedureInfo.getItemId(), itemWorkingprocedureInfo.getOrderId(), itemWorkingprocedureInfo.getWorkingProcedureId());

        //超过报废率
        if (problemNumberTotal - wasteSize > totalSize * scrapRate / 100)
            throw new IllegalArgumentException("问题数量大于报废率");

        boolean ifComplete = completeNumberTotal + completeNumber + problemNumber + problemNumberTotal >= totalSize + wastePreSum;
        if (iItemWorkingprocedureService.isLastWp(itemWorkingprocedureInfo.getItemId(), itemWorkingprocedureInfo.getWorkingProcedureId(), itemWorkingprocedure.getDept())) {
            QueryWrapper<StorageRecord> storageRecordQueryWrapper = new QueryWrapper<>();
            storageRecordQueryWrapper.eq("orderId", itemWorkingprocedureInfo.getOrderId());
            storageRecordQueryWrapper.eq("itemId", itemWorkingprocedureInfo.getItemId());
            storageRecordQueryWrapper.eq("status", StorageStatusEnum.SQRK.getCode());
            StorageRecord one = iStorageRecordService.getOne(storageRecordQueryWrapper);
            if (one == null) { //仓库流水中如果没有申请入库的  就新增一个
                StorageRecord storageRecord = new StorageRecord();
                storageRecord.setStorageType(StorageType.CPK);
                storageRecord.setItemId(itemWorkingprocedureInfo.getItemId());
                storageRecord.setOrderId(itemWorkingprocedureInfo.getOrderId());
                storageRecord.setSize(itemWorkingprocedureInfo.getCompleteNumber());
                storageRecord.setStatus(StorageStatusEnum.SQRK);
                iStorageRecordService.save(storageRecord);
            }else {//仓库流水中已经有待申请入库的了  就直接在上面加数字就行了
                one.setSize(one.getSize() + itemWorkingprocedureInfo.getCompleteNumber());
                iStorageRecordService.updateById(one);
            }

            if (ifComplete) {
                orderItem.setStatus(OrderItemStatusEnum.DRK);
                iOrderItemService.updateById(orderItem);
            }
        }

        if (ifComplete) {
            List<ItemWorkingprocedureDevice> workingprocedureDevices = iItemWorkingprocedureDeviceService.findByWorkingprocedureId(itemWorkingprocedureInfo.getWorkingProcedureId(), itemWorkingprocedureInfo.getOrderId());
            if (null != workingprocedureDevices) {
                workingprocedureDevices.forEach(itemWorkingprocedureDevice ->
                        iDeviceService.updateStatus(itemWorkingprocedureDevice.getDeviceId(), DeviceStatusEnum.DFP)
                );
            }
        }

        if (orderItem.getStatus().equals(OrderItemStatusEnum.DSC)) {
            orderItem.setStatus(OrderItemStatusEnum.SCZ);
            iOrderItemService.updateById(orderItem);
        }

        return itemWorkingprocedureInfoMapper.insert(itemWorkingprocedureInfo);
    }

    @Override
    public void repair(long wpInfoId, int repairCount) {
        ItemWorkingprocedureInfo itemWorkingprocedureInfo = itemWorkingprocedureInfoMapper.selectById(wpInfoId);
        Integer problemNumber = itemWorkingprocedureInfo.getProblemNumber();
        Integer completeNumber = itemWorkingprocedureInfo.getCompleteNumber();
        if (repairCount > problemNumber) {
            throw new IllegalArgumentException("修复数量大于问题数量");
        }
        itemWorkingprocedureInfo.setCompleteNumber(completeNumber + repairCount);
        itemWorkingprocedureInfo.setProblemNumber(problemNumber - repairCount);

        itemWorkingprocedureInfoMapper.updateById(itemWorkingprocedureInfo);
    }
}
